package com.leezai.mqtt.config;

import com.leezai.mqtt.dto.HexDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 静态解析配置工具类
 * 不依赖Spring容器管理
 */
public class ParserConfig {

    private static final Logger log = LoggerFactory.getLogger(ParserConfig.class);
    private static final Map<String, List<HexDto>> topicRules = new ConcurrentHashMap<>();
    private static volatile boolean initialized = false;

    // 私有构造函数，防止实例化
    private ParserConfig() {}

    /**
     * 初始化配置（在应用启动时调用）
     */
    public static synchronized void initialize() {
        if (initialized) {
            return;
        }
        try {
            loadFromYaml();
            initialized = true;
        } catch (Exception e) {
            log.error("Failed to initialize ParserConfig: " + e.getMessage(), e);
        }
    }

    /**
     * 从YAML文件加载配置
     */
    private static void loadFromYaml() {
        try {
            // 获取环境变量或系统属性指定的配置文件后缀
            String profile = getActiveProfile();
            List<InputStream> configStreams = getConfigResources(profile);

            // 按优先级加载配置文件
            boolean loaded = false;
            for (InputStream inputStream : configStreams) {
                if (inputStream != null) {
                    try {
                        loadYamlFromStream(inputStream);
                        loaded = true;
                        break; // 找到第一个存在的配置文件就停止
                    } catch (Exception e) {
                        log.warn("Failed to load configuration from stream", e);
                    } finally {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            log.warn("Failed to close input stream", e);
                        }
                    }
                }
            }

            // 如果没有找到配置文件，尝试默认配置文件
            if (!loaded) {
                try (InputStream defaultStream = Thread.currentThread()
                        .getContextClassLoader()
                        .getResourceAsStream("application.yml")) {
                    if (defaultStream != null) {
                        loadYamlFromStream(defaultStream);
                        loaded = true;
                    }
                } catch (Exception e) {
                    log.warn("Failed to load default configuration", e);
                }
            }

            if (!loaded) {
                log.warn("No configuration file found, using default configuration");
            }

        } catch (Exception e) {
            log.error("Error loading YAML configuration: " + e.getMessage(), e);
        }
    }

    /**
     * 获取当前激活的配置文件后缀
     */
    private static String getActiveProfile() {
        // 优先级1: 系统属性
        String profile = System.getProperty("spring.profiles.active");
        if (profile != null && !profile.isEmpty()) {
            return profile;
        }

        // 优先级2: 环境变量
        profile = System.getenv("SPRING_PROFILES_ACTIVE");
        if (profile != null && !profile.isEmpty()) {
            return profile;
        }

        return null; // 没有指定profile
    }

    /**
     * 根据profile获取配置文件流列表（按优先级排序）
     */
    private static List<InputStream> getConfigResources(String profile) {
        List<InputStream> streams = new ArrayList<>();

        if (profile != null && !profile.isEmpty()) {
            // 根据逗号分隔的多个profile
            String[] profiles = profile.split(",");
            for (String p : profiles) {
                p = p.trim();
                if (!p.isEmpty()) {
                    // application-{profile}.yml
                    InputStream stream1 = Thread.currentThread()
                            .getContextClassLoader()
                            .getResourceAsStream("application-" + p + ".yml");
                    if (stream1 != null) streams.add(stream1);

                    InputStream stream2 = Thread.currentThread()
                            .getContextClassLoader()
                            .getResourceAsStream("application-" + p + ".yaml");
                    if (stream2 != null) streams.add(stream2);
                }
            }
        }

        // 添加默认配置文件
        InputStream defaultYml = Thread.currentThread()
                .getContextClassLoader()
                .getResourceAsStream("application.yml");
        if (defaultYml != null) streams.add(defaultYml);

        InputStream defaultYaml = Thread.currentThread()
                .getContextClassLoader()
                .getResourceAsStream("application.yaml");
        if (defaultYaml != null) streams.add(defaultYaml);

        return streams;
    }

    /**
     * 从指定输入流加载YAML配置
     */
    @SuppressWarnings("unchecked")
    private static void loadYamlFromStream(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            return;
        }

        try {
            Yaml yaml = new Yaml();
            Map<String, Object> yamlData = yaml.load(inputStream);

            if (yamlData != null) {
                // 解析配置结构: mqtt.parser.topic-rules
                Map<String, Object> mqttConfig = (Map<String, Object>) yamlData.get("mqtt");
                if (mqttConfig != null) {
                    Map<String, Object> parserConfig = (Map<String, Object>) mqttConfig.get("parser");
                    if (parserConfig != null) {
                        Map<String, Object> rulesConfig = (Map<String, Object>) parserConfig.get("topic-rules");
                        if (rulesConfig != null) {
                            // 手动转换配置
                            Map<String, List<HexDto>> rules = new ConcurrentHashMap<>();
                            for (Map.Entry<String, Object> entry : rulesConfig.entrySet()) {
                                String topic = entry.getKey();
                                Object topicRulesObj = entry.getValue();

                                if (topicRulesObj instanceof List) {
                                    List<Map<String, Object>> ruleList = (List<Map<String, Object>>) topicRulesObj;
                                    List<HexDto> hexDtos = new ArrayList<>();

                                    for (Map<String, Object> ruleMap : ruleList) {
                                        HexDto hexDto = new HexDto();
                                        // 手动设置HexDto的属性
                                        if (ruleMap.containsKey("name")) {
                                            hexDto.setName((String) ruleMap.get("name"));
                                        }
                                        if (ruleMap.containsKey("start-position")) {
                                            Object startPosObj = ruleMap.get("start-position");
                                            if (startPosObj instanceof Number) {
                                                hexDto.setStartPosition(((Number) startPosObj).intValue());
                                            }
                                        }
                                        if (ruleMap.containsKey("length")) {
                                            Object lengthObj = ruleMap.get("length");
                                            if (lengthObj instanceof Number) {
                                                hexDto.setLength(((Number) lengthObj).intValue());
                                            }
                                        }
                                        if (ruleMap.containsKey("type")) {
                                            hexDto.setType((String) ruleMap.get("type"));
                                        }
                                        if (ruleMap.containsKey("scale")) {
                                            Object scaleObj = ruleMap.get("scale");
                                            if (scaleObj instanceof Number) {
                                                hexDto.setScale(((Number) scaleObj).floatValue());
                                            }
                                        }

                                        hexDtos.add(hexDto);
                                    }

                                    rules.put(topic, hexDtos);
                                }
                            }

                            topicRules.clear(); // 清空现有规则
                            topicRules.putAll(rules);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("Error parsing YAML configuration: " + e.getMessage(), e);
            throw new IOException("Failed to parse YAML configuration", e);
        }
    }

    /**
     * 手动设置规则 清空后添加
     */
    public static void setTopicRules(Map<String, List<HexDto>> rules) {
        topicRules.clear();
        if (rules != null) {
            topicRules.putAll(rules);
        }
        initialized = true;
    }

    /**
     * 添加特定主题的规则
     */
    public static void addTopicRules(String topic, List<HexDto> rules) {
        if (topic != null && rules != null) {
            topicRules.put(topic, new ArrayList<>(rules));
        }
        initialized = true;
    }

    /**
     * 获取所有规则
     */
    public static Map<String, List<HexDto>> getTopicRules() {
        return new ConcurrentHashMap<>(topicRules);
    }

    /**
     * 获取特定主题的规则
     */
    public static List<HexDto> getRulesForTopic(String topic) {
        return topicRules.get(topic);
    }

    /**
     * 检查是否已初始化
     */
    public static boolean isInitialized() {
        return initialized;
    }

    /**
     * 清除配置
     */
    public static void clear() {
        topicRules.clear();
        initialized = false;
    }
}
